/***************************************************************************************
 * Copyright 2020 Infineon Technologies AG ( www.infineon.com ).                       *
 * All rights reserved.                                                                *
 *                                                                                     *
 * Licensed  Material-Property of Infineon Technologies AG.                            *
 * This software is made available solely pursuant to the terms of Infineon            *
 * Technologies AG agreement which governs its use. This code and the information      *
 * contained in it are proprietary and confidential to Infineon Technologies AG.       *
 * No person is allowed to copy, reprint, reproduce or publish any part of this code,  *
 * nor disclose its contents to others, nor make any use of it, nor allow or assist    *
 * others to make any use of it - unless by prior Written express authorization of     *
 * Infineon Technologies AG and then only to the extent authorized.                    *
 *                                                                                     *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,            *
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,           *
 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED.  IN NO       *
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,                 *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;         *
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY             *
 * WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR            *
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF              *
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                          *
 *                                                                                     *
 ***************************************************************************************/
/**
 * @file   auths_api.h
 * @date   June, 2020
 * @brief  Implementation of Authenticate S API
 */
#ifndef AUTHENTICATE_AUTHS_API_H_
#define AUTHENTICATE_AUTHS_API_H_

#pragma once

#include <stdio.h>
#include <stdint.h>

#include "register.h"
#include "nvm.h"


#include "interface.h"
#include "auths_config.h"
#include "gpo.h"
#include "crypto_lib.h"

#include "i2c_bus.h"
//todo System porting required: implements platform header, if required.

typedef enum CONFIG_TYPE_ {
	NVM_RESET_CONFIG,
	HS_MODE_CONFIG,
	CHIPLOCK_CONFIG,
	LSC_RESET_CONFIG,
	HOSTAUTH_CONFIG,
	AUTOKILL_CONFIG,
	KILL_CONFIG
} CONFIG_TYPE;

typedef enum UID_ORDER_ {MSB_FIRST, LSB_FIRST} UID_ORDER;

/** @brief Type of event handling */
typedef enum EVENT_HANDLE_{
	POLLING,
	INTERRUPT,
	FIXED_WAIT
} EVENT_HANDLE;

/** @brief Device communication interface */
typedef enum INTERFACE_TYPE_{
	UNDEFINED_INTERFACE,
	I2C,
	SWI,
} INTERFACE_TYPE;

typedef enum UID_SEARCH_ {UID_BY_SEARCH, UID_BY_REGISTER_READ} UID_SEARCH_TYPE;

/** @brief SWI property */
typedef struct{
 //todo System porting required: implements platform GPIO, if required.
	uint16_t *gpio;

	uint8_t Overwrite_Default_timing;

	uint16_t WakeUpDelay_time;		
	uint16_t Highspeed_Baud_low;
	uint16_t Highspeed_Baud_high;
	uint16_t Highspeed_Baud_stop;
	uint16_t Highspeed_Response_timeout;
	uint32_t ECC_Response_timeout;
	uint16_t Lowspeed_Baud_low;
	uint16_t Lowspeed_Baud_high;
	uint16_t Lowspeed_Baud_stop;
	uint16_t Lowspeed_Response_timeout;
	uint16_t PowerDown_time;
	uint16_t PowerUp_time;
	uint16_t Reset_time;
	uint16_t NVMRetryCount;
	uint8_t device_address;
	uint8_t device_count;
	uint8_t UID_by_search;
}SWI_TYPE;

/** @brief I2C property */
typedef struct{
 //todo System porting required: implements platform I2C, if required.
	uint16_t *SDA;
	uint16_t *SCL;

	uint32_t frequency;
	uint8_t device_address;
	uint8_t device_count;
}I2C_TYPE;

/** @brief GPO property */
typedef struct{
 //todo System porting required: implements platform GPIO, if required.
	uint16_t *gpo;	
	uint8_t config;//Pull-up weak, strong, etc
}GPO_TYPE;

/** @brief Active interface property */
union INTERFACE_UNION{
	I2C_TYPE i2c;
	SWI_TYPE swi;
} ;

/** @brief Device active interface */
struct AuthS_INTERFACE{
	INTERFACE_TYPE active_interface;
	union INTERFACE_UNION interface;
	uint16_t *gpo;	
};
typedef struct AuthS_INTERFACE AuthS_Interface;

typedef enum HOST_AUTH_STATUS_ {host_auth_not_done, host_auth_done} HOST_AUTH_STATUS;
typedef enum ECC_AUTH_STATUS_ {ecc_not_done, ecc_done} ECC_AUTH_STATUS;
typedef enum FEATURE {unsupported, supported} feature;

/** @brief Optional configurable features */
struct DEVICE_ATTRIBUTE{
	feature host_authentication_support;
	feature kill_ecc_support;
	feature auto_kill_ecc;
	feature lsc_restore_support;
	feature user_nvm_unlock;
	feature gpo_trigger_authentication;
	feature gpo_trigger_lsc2;
};

/** @brief Alternate functions */
void auths_alt_rng(uint8_t* random_byte, uint8_t len);
void auths_alt_sha(uint8_t* sha_in, uint8_t *sha_out, uint16_t len);

/** @brief Device capabilities */
struct AuthS_CAPABILITY{
	INTERFACE_TYPE active_interface;
	union INTERFACE_UNION interface;
 //todo System porting required: implements platform GPIO, if required.
	uint16_t *gpo;	

	//UID property
	uint8_t uid[UID_BYTE_LEN];
	uint8_t uid_length;
	
	//NVM property
	uint16_t nvm_size;
	uint16_t nvm_page_count;

	//Crypto property
	ECC_AUTH_STATUS ecc_done;
	HOST_AUTH_STATUS host_auth_done;
	uint16_t odc_bit_length;
	uint16_t ecc_bit_length;
	uint8_t num_lsc_counter;
	uint8_t num_ecc_keypair;

	struct DEVICE_ATTRIBUTE device_attribute;

	//alternate functions
	void (*auths_alt_rng)(uint8_t* random_byte, uint8_t len);
	void (*auths_alt_sha)(uint8_t* sha_in, uint8_t *sha_out, uint32_t len);
};

typedef struct AuthS_CAPABILITY AuthS_Capability;
//struct AuthS_CAPABILITY *AuthS_Capability_Ptr;

/** @brief support for multiple device on bus */
struct AuthS_ENUMERATION{
	uint8_t UID[DEVICES_ON_BUS][12];
	uint16_t device_address[DEVICES_ON_BUS];
	uint16_t active_device;
	uint16_t device_found;
};
typedef struct AuthS_ENUMERATION AuthS_Enumeration;

/** SDK Configuration API */
uint16_t auths_get_sdk_version(uint16_t *version, uint32_t*date);
uint16_t auths_init_sdk(AuthS_Interface interface, AuthS_Capability *AuthS_Capability_Handle);
uint16_t auths_get_active_interface(INTERFACE_TYPE* active_interface);
uint16_t auths_deinit_sdk(void);
uint16_t auths_get_sdk_device_found(uint8_t *device_found);
uint16_t auths_get_sdk_active_device(uint8_t *active_device);
uint16_t auths_set_sdk_active_device(uint8_t active_device);
uint16_t auths_set_sdk_active_device_uid(uint8_t * active_device_uid, uint8_t invert_uid);

/** I2C Interface API */
uint16_t auths_exe_search_i2c_address(uint16_t* i2c_address, uint8_t* UID, uint8_t* device_count);
uint16_t auths_sdk_set_active_i2c_address(uint8_t i2c_address);
uint16_t auths_sdk_get_active_i2c_address(uint8_t *i2c_address);
uint16_t auths_get_i2c_address (uint8_t i2c_address,  uint8_t* i2c_address_register);
uint16_t auths_set_i2c_address (uint8_t current_i2c_address,  uint8_t new_i2c_address);
uint16_t auths_read_i2c_sfr(uint8_t i2c_address, uint16_t sfr_address, uint8_t *sfr_value, uint16_t length);
uint16_t auths_write_i2c_sfr(uint8_t i2c_address, uint16_t sfr_address, uint8_t *sfr_value, uint16_t length);

uint16_t auths_get_swi_address(uint16_t* device_address);
uint16_t auths_set_swi_address(uint16_t device_address);
uint16_t auths_read_swi_sfr(uint16_t sfr_address, uint8_t *sfr_value, uint16_t length);
uint16_t auths_write_swi_sfr(uint16_t sfr_address, uint8_t *sfr_value, uint16_t length);

/** Device Characteristics API*/
uint16_t auths_exe_read_uid(uint8_t* uid, uint8_t *vid, uint8_t *pid);
uint16_t auths_get_device_capability (AuthS_Capability* device_capability);
uint16_t auths_exe_reset(void);
uint16_t auths_exe_power_cycle(void);
uint16_t auths_exe_power_down(void);
uint16_t auths_exe_power_up(void);

/** Host Authentication API */
uint16_t auths_exe_host_authentication(void);
uint16_t auths_is_host_auth_done(HOST_AUTH_STATUS* status);

/** ECC API */
uint16_t auths_exe_ecc(uint8_t key_number, uint8_t mac_group);
uint16_t auths_get_ecc_kill_status(void);
uint16_t auths_exe_kill_ecc( uint8_t mac_id);
uint16_t auths_get_ecc_publickey(uint8_t key_number, uint8_t *public_key);
uint16_t auths_get_odc(uint8_t key_number, uint8_t* odc_value);
uint16_t auths_get_hash(uint8_t key_number, uint8_t* hash_value);

/** NVM API */
uint16_t auths_read_nvm(uint16_t nvm_start_page, uint8_t *ubp_data, uint8_t page_count);
uint16_t auths_write_nvm(uint16_t nvm_start_page, uint8_t *ubp_Data, uint8_t page_count);
uint16_t Cmd_Yfl_Get_Memory_Page(uint16_t addr, uint8_t *data);
uint16_t Cmd_Yfl_Set_Memory_Page(uint16_t addr,uint8_t *data);
uint16_t auths_set_nvm_page_lock(uint8_t page);
uint16_t auths_get_nvm_lock_status(uint8_t page);
uint16_t auths_exe_mac_nvm(uint16_t page, uint8_t mac_id);
uint16_t auths_reset_lsc(uint8_t lsc_number);
uint16_t auths_unlock_nvm_locked(void);
uint16_t auths_get_ifx_config(CONFIG_TYPE config_type);

/** LSC API */ 
uint16_t auths_set_lsc_value(uint8_t lsc_select, uint32_t lsc_value);
uint16_t auths_get_lsc_value(uint8_t lsc_select, uint32_t * lsc_value);
uint16_t Hal_Yfl_Read_Counter_Value(uint32_t *dcvalue);
uint16_t auths_set_lsc_decvalue(uint8_t lsc_select, uint16_t uw_lsc_DecVal);
uint16_t Hal_Yfl_Write_Counter_Value(void);
uint16_t auths_get_lsc_decvalue(uint16_t *uw_lsc_DecVal );

uint16_t auths_set_lsc1_autodec(void);
uint16_t auths_set_lsc_protection(uint8_t lsc_number);
uint16_t auths_set_lsc_zero(uint8_t lsc_number);
uint16_t auths_get_lsc_lock_status(uint8_t lsc_number);

/** GPO API */
uint16_t auths_get_gpo_level(uint8_t *ub_gpo_level);
uint16_t auths_set_gpo_config(GPO_status gpo_value);
uint16_t auths_get_gpo_config(GPO_status *gpo_config);

#endif /* AUTHENTICATE_AUTHS_API_H_ */
